<template>
  <div 
    ref="element" 
    :class="{ 
      'animate': true, 
      'animate-fade-up': animation === 'fade-up',
      'animate-fade-right': animation === 'fade-right',
      'animate-fade-left': animation === 'fade-left',
      'animate-zoom-in': animation === 'zoom-in',
      'is-visible': isVisible
    }"
    :style="animationStyle"
  >
    <slot></slot>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue';

const props = defineProps({
  animation: {
    type: String,
    default: 'fade-up',
    validator: (value: string) => ['fade-up', 'fade-right', 'fade-left', 'zoom-in'].includes(value)
  },
  threshold: {
    type: Number,
    default: 0.2
  },
  delay: {
    type: Number,
    default: 0
  }
});

const element = ref<HTMLElement | null>(null);
const isVisible = ref(false);
let observer: IntersectionObserver | null = null;

// 计算动画样式，包括延迟
const animationStyle = computed(() => {
  return {
    'transition-delay': `${props.delay}s`
  };
});

onMounted(() => {
  // 确保Intersection Observer API存在
  if ('IntersectionObserver' in window) {
    observer = new IntersectionObserver(entries => {
      const [entry] = entries;
      if (entry.isIntersecting) {
        // 元素进入视口，应用动画
        isVisible.value = true;
        
        // 一旦动画触发，就不再需要观察
        if (observer && element.value) {
          observer.unobserve(element.value);
        }
      }
    }, {
      threshold: props.threshold,
      rootMargin: '0px'
    });
    
    if (element.value) {
      observer.observe(element.value);
    }
  } else {
    // 如果浏览器不支持Intersection Observer，则直接显示元素
    isVisible.value = true;
  }
});

onUnmounted(() => {
  if (observer && element.value) {
    observer.unobserve(element.value);
    observer.disconnect();
  }
});
</script>

<style scoped>
.animate {
  transition-duration: 0.8s;
  transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
  transition-property: opacity, transform;
  will-change: opacity, transform;
}

.animate-fade-up {
  opacity: 0;
  transform: translateY(50px);
}

.animate-fade-right {
  opacity: 0;
  transform: translateX(-50px);
}

.animate-fade-left {
  opacity: 0;
  transform: translateX(50px);
}

.animate-zoom-in {
  opacity: 0;
  transform: scale(0.9);
}

.is-visible {
  opacity: 1 !important;
  transform: translate(0) scale(1) !important;
}

@media (prefers-reduced-motion: reduce) {
  .animate {
    transition: none;
    transform: none;
    opacity: 1;
  }
}
</style> 